import * as Cesium from 'cesium'

const prefix = import.meta.env.VITE_BASE_URL
export default class DrawUtil {
  circle
  rectangle
  clickEventListener    // click事件
  constructor(viewer, type, div) {
    this.viewer = viewer
    this.type = type
    this.div = div
    this.tempEntities = new Cesium.EntityCollection()     // 添加Entity的数组
    this.tempPrimitives = new Cesium.PrimitiveCollection()  // 添加Primitive数据
    this.viewer.scene.primitives.destroyPrimitives = false
  }
  addDrawUtil() {
    switch (this.type) {
      case 'drawPoint':
        this.addDrawPoint()
        break
      case 'drawLineString':
        this.addDrawLineString()
        break
      case 'drawPolygon':
        this.addDrawPolygon()
        break
      case 'drawCircle':
        this.addDrawCircle()
        break
      case 'drawRectangle':
        this.addDrawRectangle()
        break
    }
  }
  // 绘制点
  drawPoint(position) {
    let point = this.viewer.entities.add({
      name: '点几何对象',
      position: position,
      billboard: {
        color: Cesium.Color.YELLOW,
        image: prefix + '/images/map-marker.png',
        scale: 0.2,
        disableDepthTestDistance: Number.POSITIVE_INFINITY
      }
    })
    this.tempEntities.add(point)
    return point
  }
  // 绘制线
  drawPolyline(positions) {
    if (positions.length < 1) return
    let line = this.viewer.entities.add({
      name: "线几何对象",
      polyline: {
        positions: positions,
        width: 5.0,
        material: new Cesium.PolylineGlowMaterialProperty({
          color: Cesium.Color.GOLD,
        }),
        depthFailMaterial: new Cesium.PolylineGlowMaterialProperty({
          color: Cesium.Color.GOLD,
        })
      }
    })
    this.tempEntities.add(line)
    return line
  }
  // 绘制面
  drawPolygon(positions) {
    let polygon = this.viewer.entities.add({
      name: '面几何对象',
      polygon: {
        hierarchy: positions,
        material: new Cesium.Color.fromCssColorString("#FFD700").withAlpha(0.2)
      }
    })
    this.tempEntities.add(polygon)
    return polygon
  }
  // 绘制圆
  drawCircle(center, radius) {
    const instance = new Cesium.GeometryInstance({
      geometry: new Cesium.CircleGeometry({
        center: center,
        radius: radius,
      }),
      attributes: {
        color: Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.SKYBLUE)
      }
    })
    const circle = new Cesium.Primitive({
      name: '圆几何对象',
      geometryInstances: instance,
      appearance: new Cesium.PerInstanceColorAppearance()
    })
    this.viewer.scene.primitives.add(circle)
    this.tempPrimitives.add(circle)
    return circle
  }
  // 绘制正方形
  drawRectangle(positions) {
    const rectangle = new Cesium.Primitive({
      geometryInstances: new Cesium.GeometryInstance({
        geometry: new Cesium.RectangleGeometry({
          ellipsoid: Cesium.Ellipsoid.WGS84,
          rectangle: Cesium.Rectangle.fromDegrees(...positions)
        }),
        attributes: {
          color: Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.SKYBLUE)
        }
      }),
      appearance: new Cesium.PerInstanceColorAppearance()
    })
    this.viewer.scene.primitives.add(rectangle)
    this.tempPrimitives.add(rectangle)
    return rectangle
  }
  // 添加绘制点的工具
  addDrawPoint() {
    const that = this
    let handler = new Cesium.ScreenSpaceEventHandler(that.viewer.scene.canvas)
    // 移除默认双击事件trackedEntity
    that.viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK)
    this.clickEventListener = (e) => {
      let arr = Cesium.Cartesian2.fromArray([e.clientX, e.clientY])
      let point = that.drawPoint(that.viewer.camera.pickEllipsoid(arr, that.viewer.scene.globe.ellipsoid))
      // 鼠标移动事件
      handler.setInputAction(function (movement) {
        let position = that.viewer.camera.pickEllipsoid(movement.endPosition, that.viewer.scene.globe.ellipsoid)
        point.position = position
      }, Cesium.ScreenSpaceEventType.MOUSE_MOVE)
      // 左键点击事件
      handler.setInputAction(function (movement) {
        let position = that.viewer.camera.pickEllipsoid(movement.position, that.viewer.scene.globe.ellipsoid)
        that.drawPoint(position)
      }, Cesium.ScreenSpaceEventType.LEFT_CLICK)
      // 左键双击事件
      handler.setInputAction(function () {
        handler.destroy() //关闭事件句柄
      }, Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK)
      // 右键点击事件
      handler.setInputAction(function () {
        handler.destroy()  //关闭事件句柄
      }, Cesium.ScreenSpaceEventType.RIGHT_CLICK)
    }
    that.div.addEventListener('click', this.clickEventListener)
  }
  // 添加绘制线的工具
  addDrawLineString() {
    const that = this
    let handler = new Cesium.ScreenSpaceEventHandler(that.viewer.scene.canvas)
    // 移除默认双击事件trackedEntity
    that.viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK)
    this.clickEventListener = (e) => {
      let tempPoints = []    // 放置添加线时点的坐标数组
      let arr = Cesium.Cartesian2.fromArray([e.clientX, e.clientY])
      let point = that.drawPoint(that.viewer.camera.pickEllipsoid(arr, that.viewer.scene.globe.ellipsoid))
      handler.setInputAction(function (movement) {
        let position = that.viewer.camera.pickEllipsoid(movement.endPosition, that.viewer.scene.globe.ellipsoid)
        point.position = position
      }, Cesium.ScreenSpaceEventType.MOUSE_MOVE)
      handler.setInputAction(function (movement) {
        let position = that.viewer.camera.pickEllipsoid(movement.position, that.viewer.scene.globe.ellipsoid)
        that.drawPoint(position)
        tempPoints.push(position)
        let tempLength = tempPoints.length
        //调用绘制点的接口
        if (tempLength > 1) {
          that.drawPolyline([tempPoints.at(-2), tempPoints.at(-1)])
        }
      }, Cesium.ScreenSpaceEventType.LEFT_CLICK)
      handler.setInputAction(function () {
        handler.destroy() //关闭事件句柄
      }, Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK)
      handler.setInputAction(function () {
        handler.destroy()  //关闭事件句柄
      }, Cesium.ScreenSpaceEventType.RIGHT_CLICK)
    }
    that.div.addEventListener('click', this.clickEventListener)
  }
  // 添加绘制面的工具
  addDrawPolygon() {
    const that = this
    let handler = new Cesium.ScreenSpaceEventHandler(that.viewer.scene.canvas)
    // 移除默认双击事件trackedEntity
    that.viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK)
    this.clickEventListener = (e) => {
      let tempPoints = []    // 放置添加线时点的坐标数组
      let arr = Cesium.Cartesian2.fromArray([e.clientX, e.clientY])
      let point = that.drawPoint(that.viewer.camera.pickEllipsoid(arr, that.viewer.scene.globe.ellipsoid))
      //鼠标移动事件
      handler.setInputAction(function (movement) {
        let position = that.viewer.camera.pickEllipsoid(movement.endPosition, that.viewer.scene.globe.ellipsoid)
        point.position = position
      }, Cesium.ScreenSpaceEventType.MOUSE_MOVE)
      //左键点击操作
      handler.setInputAction(function (click) {
        //调用获取位置信息的接口
        let ray = that.viewer.camera.getPickRay(click.position)
        let position = that.viewer.scene.globe.pick(ray, that.viewer.scene)
        tempPoints.push(position)
        let tempLength = tempPoints.length
        //调用绘制点的接口
        that.drawPoint(position)
        if (tempLength > 1) {
          that.drawPolyline([tempPoints.at(-2), tempPoints.at(-1)])
        }
      }, Cesium.ScreenSpaceEventType.LEFT_CLICK)
      //双击点击绘制完成操作
      handler.setInputAction(function (click) {
        let cartesian = that.viewer.camera.pickEllipsoid(click.position, that.viewer.scene.globe.ellipsoid)
        if (cartesian) {
          let tempLength = tempPoints.length
          if (tempLength < 3) {
            alert('请选择3个以上的点再执行闭合操作命令')
          } else {
            //闭合最后一条线
            that.drawPolyline([tempPoints.at(-1), tempPoints[0]])
            that.drawPolygon(tempPoints)
            handler.destroy()//关闭事件句柄
          }
        }
      }, Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK)
    }
    that.div.addEventListener('click', this.clickEventListener)
  }
  // 添加绘制圆的工具
  addDrawCircle() {
    const that = this
    let handler = new Cesium.ScreenSpaceEventHandler(that.viewer.scene.canvas)
    that.viewer.scene.globe.depthTestAgainstTerrain = false
    // 移除默认双击事件trackedEntity
    that.viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK)
    this.clickEventListener = (e) => {
      let tempPoints = []    // 放置添加线时点的坐标数组
      let arr = Cesium.Cartesian2.fromArray([e.clientX, e.clientY])
      let point = that.drawPoint(that.viewer.camera.pickEllipsoid(arr, that.viewer.scene.globe.ellipsoid))
      // 鼠标移动事件
      handler.setInputAction(function (movement) {
        let position = that.viewer.camera.pickEllipsoid(movement.endPosition, that.viewer.scene.globe.ellipsoid)
        point.position = position
      }, Cesium.ScreenSpaceEventType.MOUSE_MOVE)
      // 左键点击操作
      handler.setInputAction(function (click) {
        //调用获取位置信息的接口
        let ray = that.viewer.camera.getPickRay(click.position)
        let position = that.viewer.scene.globe.pick(ray, that.viewer.scene)
        tempPoints.push(position)
        let tempLength = tempPoints.length
        that.drawPoint(position)
        if (tempLength > 1) {
          if (that.circle !== null) {
            // 每次绘制新的圆时都需要移除上一次绘制的圆
            that.viewer.scene.primitives.remove(that.circle)
          }
          that.viewer.entities.remove(that.tempEntities.values.at(-1))
          // 计算圆的中心到边缘的距离
          let result = Cesium.Cartesian3.distance(position, tempPoints[0])
          let primitive = that.drawCircle(tempPoints[0], result)
          that.circle = primitive
        }
      }, Cesium.ScreenSpaceEventType.LEFT_CLICK)
      // 双击点击绘制完成操作
      handler.setInputAction(function () {
        handler.destroy() //关闭事件句柄
      }, Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK)
      // 右键点击绘制完成操作
      handler.setInputAction(function () {
        handler.destroy()  //关闭事件句柄
      }, Cesium.ScreenSpaceEventType.RIGHT_CLICK)
    }
    that.div.addEventListener('click', this.clickEventListener)
  }
  // 添加绘制正方形的工具
  addDrawRectangle() {
    const that = this
    let handler = new Cesium.ScreenSpaceEventHandler(that.viewer.scene.canvas)
    // 移除默认双击事件trackedEntity
    that.viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK)
    this.clickEventListener = (e) => {
      let tempPoints = []    // 放置添加线时点的坐标数组
      let arr = Cesium.Cartesian2.fromArray([e.clientX, e.clientY])
      let point = that.drawPoint(that.viewer.camera.pickEllipsoid(arr, that.viewer.scene.globe.ellipsoid))
      // 鼠标移动事件
      handler.setInputAction(function (movement) {
        let position = that.viewer.camera.pickEllipsoid(movement.endPosition, that.viewer.scene.globe.ellipsoid)
        point.position = position
      }, Cesium.ScreenSpaceEventType.MOUSE_MOVE)
      // 左键点击操作
      handler.setInputAction(function (click) {
        //调用获取位置信息的接口
        let ray = that.viewer.camera.getPickRay(click.position)
        let position = that.viewer.scene.globe.pick(ray, that.viewer.scene)
        that.drawPoint(position)
        let a = Cesium.Cartographic.fromCartesian(position)
        position = [Cesium.Math.toDegrees(a.longitude), Cesium.Math.toDegrees(a.latitude)]
        tempPoints.push(position)
        let tempLength = tempPoints.length
        if (tempLength > 1) {
          if (that.rectangle !== null) {
            // 每次绘制新的正方形时都需要移除上一次绘制的圆
            that.viewer.scene.primitives.remove(that.rectangle)
          }
          that.viewer.entities.remove(that.tempEntities.values.at(-1))
          let rectanglePoints = [tempPoints[0][0], position[1], position[0], tempPoints[0][1]]
          let primitive = that.drawRectangle(rectanglePoints)
          that.rectangle = primitive
        }
      }, Cesium.ScreenSpaceEventType.LEFT_CLICK)
      // 双击点击绘制完成操作
      handler.setInputAction(function () {
        handler.destroy() //关闭事件句柄
      }, Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK)
      // 右键点击绘制完成操作
      handler.setInputAction(function () {
        handler.destroy()  //关闭事件句柄
      }, Cesium.ScreenSpaceEventType.RIGHT_CLICK)
    }
    that.div.addEventListener('click', this.clickEventListener)
  }
  // 移除绘制控件
  removeDrawUtil() {
    this.viewer.entities.removeAll()
    this.tempEntities.removeAll()
    for (let i = 0; i < this.tempPrimitives.length; i++) {
      this.viewer.scene.primitives.remove(this.tempPrimitives.get(i))
    }
    this.div.removeEventListener('click', this.clickEventListener)
    this.clickEventListener = null
    this.tempPrimitives.removeAll()
  }
}